home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / intrlib1.zip / CURSOR.C < prev    next >
C/C++ Source or Header  |  1992-02-23  |  11KB  |  294 lines

  1. /******************************************************************************
  2. * Iteraction library - cursor handler.                          *
  3. *                                          *
  4. *                    Written by Gershon Elber,  Oct. 1990  *
  5. *******************************************************************************
  6. * History:                                      *
  7. *  3 Oct 90 - Version 1.0 by Gershon Elber.                      *
  8. ******************************************************************************/
  9.  
  10. #include <stdio.h>
  11. #include "intr_loc.h"
  12. #include "intr_gr.h"
  13. #ifdef __MSDOS__
  14. #include "mousedrv.h"
  15. #endif /* __MSDOS__ */
  16.  
  17. #define INTR_CURSOR_STACK_SIZE 20
  18.  
  19. #ifdef DJGCC
  20. #define MouseSetPosition(x, y)    MouseWarp(x, y)
  21. #endif /* DJGCC */
  22.  
  23. static int StackPtr = 0;
  24. static int CursorLastX, CursorLastY;
  25. static IntrBType CursorVisible = FALSE;
  26. static IntrBType UseMouseDriverCursor = FALSE;
  27. static IntrCursorShapeStruct
  28.     *CurrentCursor = NULL,
  29.     CursorStack[INTR_CURSOR_STACK_SIZE];
  30.  
  31. static void IntrDrawCursor(int x, int y);
  32.  
  33. /****************************************************************************
  34. * Routine to draw cursor shape at given location. Shape is specified by     *
  35. * CurrentCursor variable.                            *
  36. ****************************************************************************/
  37. void IntrUseMouseDriverCursor(IntrBType UseMouseCursor)
  38. {
  39.     UseMouseDriverCursor = UseMouseCursor;
  40. }
  41.  
  42. /****************************************************************************
  43. * Routine to draw cursor shape at given location. Shape is specified by     *
  44. * CurrentCursor variable.                            *
  45. ****************************************************************************/
  46. static void IntrDrawCursor(int x, int y)
  47. {
  48.     int GRLastColor = GRGetColor();
  49.  
  50.     GRSetWriteMode(GR_XOR_PUT);
  51.     GRPushViewPort();
  52.     GRSetViewPort(0, 0, GRScreenMaxX, GRScreenMaxY);
  53.  
  54.     IntrAllocColor(INTR_COLOR_WHITE, INTR_INTENSITY_VHIGH);
  55.  
  56.     switch (CurrentCursor -> CursorType) {
  57.     case INTR_CURSOR_CROSS:
  58.         GRSetLineStyle(GR_DOTTED_LINE, 0, GR_NORM_WIDTH);
  59.         GRSLine(0, y, GRScreenMaxX, y);
  60.         GRSLine(x, 0, x, GRScreenMaxY);
  61.         break;
  62.     case INTR_CURSOR_CROSS_LAST:
  63.         GRSetLineStyle(GR_DOTTED_LINE, 0, GR_NORM_WIDTH);
  64.         GRSLine(0, y, GRScreenMaxX, y);
  65.         GRSLine(x, 0, x, GRScreenMaxY);
  66.         if (CurrentCursor -> LastHV) {
  67.         if (ABS(CurrentCursor -> LastX - x) <
  68.                 ABS(CurrentCursor -> LastY - y))
  69.             GRSLine(CurrentCursor -> LastX, CurrentCursor -> LastY,
  70.                         CurrentCursor -> LastX, y);
  71.         else
  72.             GRSLine(CurrentCursor -> LastX, CurrentCursor -> LastY,
  73.                     x, CurrentCursor -> LastY);
  74.         }
  75.         else
  76.         GRSLine(CurrentCursor -> LastX, CurrentCursor -> LastY,
  77.                     x, y);
  78.         break;
  79.     case INTR_CURSOR_SCROSS:
  80.         GRSetLineStyle(GR_SOLID_LINE, 0, GR_NORM_WIDTH);
  81.         GRSLine(x - 5, y - 1, x + 5, y - 1);
  82.         GRSLine(x - 5, y,     x + 5, y    );
  83.         GRSLine(x - 5, y + 1, x + 5, y + 1);
  84.         GRSLine(x - 1, y - 5, x - 1, y + 5);
  85.         GRSLine(x,     y - 5, x,     y + 5);
  86.         GRSLine(x + 1, y - 5, x + 1, y + 5);
  87.         break;
  88.     case INTR_CURSOR_CUSTOM:
  89.         (CurrentCursor -> CursorRoutine)(x, y);/* Apply crnt cursor rtn. */
  90.         break;
  91.     case INTR_CURSOR_BOX:
  92.         GRSetLineStyle(GR_DOTTED_LINE, 0, GR_NORM_WIDTH);
  93.         GRSLine(0, y, GRScreenMaxX, y);
  94.         GRSLine(x, 0, x, GRScreenMaxY);
  95.         GRSMoveTo(x - CurrentCursor -> Width, y - CurrentCursor -> Height);
  96.         GRSLineTo(x + CurrentCursor -> Width, y - CurrentCursor -> Height);
  97.         GRSLineTo(x + CurrentCursor -> Width, y + CurrentCursor -> Height);
  98.         GRSLineTo(x - CurrentCursor -> Width, y + CurrentCursor -> Height);
  99.         GRSLineTo(x - CurrentCursor -> Width, y - CurrentCursor -> Height);
  100.         break;
  101.     case INTR_CURSOR_BOX_LAST:
  102.         GRSetLineStyle(GR_DOTTED_LINE, 0, GR_NORM_WIDTH);
  103.         GRSLine(0, y, GRScreenMaxX, y);
  104.         GRSLine(x, 0, x, GRScreenMaxY);
  105.         GRSLine(x, CurrentCursor -> LastY,
  106.                 CurrentCursor -> LastX, CurrentCursor -> LastY);
  107.         GRSLine(CurrentCursor -> LastX, y,
  108.                 CurrentCursor -> LastX, CurrentCursor -> LastY);
  109.         break;
  110.     case INTR_CURSOR_ARROW:
  111.     case INTR_CURSOR_MASK:
  112.     default:
  113.         GRPutArrowCursor(x, y);
  114.         break;
  115.     }
  116.  
  117.     GRSetColor(GRLastColor);
  118.     GRPopViewPort();
  119.     GRSetLineStyle(GR_SOLID_LINE, 0, GR_NORM_WIDTH);
  120.     GRSetWriteMode(GR_COPY_PUT);
  121. }
  122.  
  123. /****************************************************************************
  124. * Routine to push cursor type into cursor stack.                *
  125. ****************************************************************************/
  126. void IntrPushCursorType(void)
  127. {
  128.     IntrSetCursorType2(INTR_CURSOR_PUSH, NULL, 0, 0, 0, 0, FALSE);
  129. }
  130.  
  131. /****************************************************************************
  132. * Routine to pop cursor type from cursor stack.                    *
  133. ****************************************************************************/
  134. void IntrPopCursorType(void)
  135. {
  136.     IntrSetCursorType2(INTR_CURSOR_POP, NULL, 0, 0, 0, 0, FALSE);
  137. }
  138.  
  139. /****************************************************************************
  140. * Routine to get current cursor shape.                        *
  141. ****************************************************************************/
  142. IntrCursorShapeStruct *IntrGetCursorType(void)
  143. {
  144.     return CurrentCursor;
  145. }
  146.  
  147. /****************************************************************************
  148. * Routine to put cursor shape at given location.                *
  149. ****************************************************************************/
  150. void IntrSetCursorType(IntrCursorShapeStruct *Cursor)
  151. {
  152.     if (Cursor != NULL)
  153.         IntrSetCursorType2(Cursor -> CursorType,
  154.                    Cursor -> CursorRoutine,
  155.                            Cursor -> Width, Cursor -> Height,
  156.                            Cursor -> LastX, Cursor -> LastY,
  157.                    Cursor -> LastHV);
  158. }
  159.  
  160. /****************************************************************************
  161. * Routine to put cursor shape at given location. Cursor type is selected    *
  162. * globaly by CursorType variable.                        *
  163. ****************************************************************************/
  164. void IntrSetCursorType2(IntrCursorType CursorType,
  165.                 void (* CursorRoutine)(int, int),
  166.                 int Width, int Height, int LastX, int LastY,
  167.                 IntrBType LastHV)
  168. {
  169.     CurrentCursor = &CursorStack[StackPtr];
  170.  
  171.     switch (CursorType) {
  172.     case INTR_CURSOR_PUSH:
  173.         if (StackPtr >= INTR_CURSOR_STACK_SIZE - 2)
  174.         IntrFatalError("Cursor stack overflow");
  175.             CurrentCursor -> LastX = GRCurrentCursorX;
  176.             CurrentCursor -> LastY = GRCurrentCursorY;
  177.             CurrentCursor -> _CursorVisible = CursorVisible;
  178.         CursorStack[StackPtr + 1] = CursorStack[StackPtr];
  179.         CurrentCursor = &CursorStack[++StackPtr];
  180.             if (CursorVisible) IntrUnShowCursor();
  181.         break;
  182.     case INTR_CURSOR_POP:
  183.         if (--StackPtr < 0)
  184.         IntrFatalError("Cursor stack underflow");
  185.         CurrentCursor = &CursorStack[StackPtr];
  186.             GRCurrentCursorX = CurrentCursor -> LastX;
  187.             GRCurrentCursorY = CurrentCursor -> LastY;
  188.             if (CurrentCursor -> _CursorVisible)
  189.                IntrShowCursor(GRCurrentCursorX, GRCurrentCursorY);
  190.         break;
  191.     case INTR_CURSOR_CROSS:
  192.     case INTR_CURSOR_CROSS_LAST:
  193.     case INTR_CURSOR_SCROSS:
  194.     case INTR_CURSOR_ARROW:
  195.     case INTR_CURSOR_CUSTOM:
  196.     case INTR_CURSOR_BOX:
  197.     case INTR_CURSOR_BOX_LAST:
  198.         CurrentCursor -> CursorType = CursorType;
  199.         CurrentCursor -> CursorRoutine = CursorRoutine;
  200.         CurrentCursor -> CursorType = CursorType;
  201.         CurrentCursor -> Width = Width;
  202.         CurrentCursor -> Height = Height;
  203.         CurrentCursor -> LastX = LastX;
  204.         CurrentCursor -> LastY = LastY;
  205.         CurrentCursor -> LastHV = LastHV;
  206.         break;
  207.     }
  208. }
  209.  
  210. /****************************************************************************
  211. * Routine to enable cursor display at a given location. Shape is specified  *
  212. * by CurrentCursor variable.                            *
  213. ****************************************************************************/
  214. void IntrShowCursor(int x, int y)
  215. {
  216.     if (CursorVisible)
  217.         IntrFatalError("Cursor is already visible.");
  218.  
  219.     CursorVisible = TRUE;
  220.  
  221.     if (_IntrActiveDevices & INTR_INPT_DEVICE_MOUSE &&
  222.         (x != CursorLastX || y != CursorLastY)) {
  223.     /* Update mouse on new position. */
  224.     MouseSetPosition(x, y);
  225.     }
  226.  
  227. #ifdef __MSDOS__
  228.     /* If this is a mouse mask and mouse exists do it using mouse driver. */
  229.     if (UseMouseDriverCursor &&
  230.         (CurrentCursor -> CursorType == INTR_CURSOR_MASK ||
  231.          CurrentCursor -> CursorType == INTR_CURSOR_ARROW) &&
  232.     _IntrActiveDevices & INTR_INPT_DEVICE_MOUSE) {
  233.         MouseShowCursor();
  234.     }
  235.     else
  236. #endif /* __MSDOS__ */
  237.         IntrDrawCursor(x, y);
  238.  
  239.     CursorLastX = x;
  240.     CursorLastY = y;
  241. }
  242.  
  243. /****************************************************************************
  244. * Routine to reposition the cursor. If the cursor is visible, it is redrawn.*
  245. ****************************************************************************/
  246. void IntrReposCursor(int x, int y)
  247. {
  248.     if (CursorVisible) {
  249.         if (_IntrActiveDevices & INTR_INPT_DEVICE_MOUSE &&
  250.            (x != CursorLastX || y != CursorLastY)) {
  251.        /* Update mouse on new position. */
  252.        MouseSetPosition(x, y);
  253.     }
  254.  
  255.     /* This is a mouse mask and mouse exists do it using mouse driver. */
  256.      if (CurrentCursor -> CursorType == INTR_CURSOR_MASK &&
  257.            _IntrActiveDevices & INTR_INPT_DEVICE_MOUSE) {
  258.         }
  259.         else {
  260.             IntrDrawCursor(CursorLastX, CursorLastY);
  261.             IntrDrawCursor(x, y);
  262.         }
  263.  
  264.         CursorLastX = x;
  265.         CursorLastY = y;
  266.     }
  267. }
  268.  
  269. /****************************************************************************
  270. * Routine to disable cursor display.                        *
  271. ****************************************************************************/
  272. void IntrUnShowCursor(void)
  273. {
  274.    if (!CursorVisible)
  275.        IntrFatalError("Cursor is already invisible.");
  276.  
  277. #ifdef __MSDOS__
  278.     /* If this is a mouse mask and mouse exists do it using mouse driver. */
  279.     if (UseMouseDriverCursor &&
  280.         (CurrentCursor -> CursorType == INTR_CURSOR_MASK ||
  281.          CurrentCursor -> CursorType == INTR_CURSOR_ARROW) &&
  282.     _IntrActiveDevices & INTR_INPT_DEVICE_MOUSE) {
  283.         MouseHideCursor();
  284.     }
  285.     else
  286. #endif /* __MSDOS__ */
  287.         IntrDrawCursor(CursorLastX, CursorLastY);
  288.  
  289.    CursorLastX = -1000;
  290.    CursorLastY = -1000;
  291.  
  292.    CursorVisible = FALSE;
  293. }
  294.